#include "stdafx.h"
#include <stdio.h>
#include "gtest/gtest.h"
#include "MathTest.h"

using namespace rs;


class Vector4Test : public MathTest
{
};


TEST_F(Vector4Test, ctor)
{
	// Vector4(f32, f32, f32, f32)
	const Vector4 v0(x0, y0, z0, w0);
	EXPECT_FLOAT_EQ(x0, v0.getX());
	EXPECT_FLOAT_EQ(y0, v0.getY());
	EXPECT_FLOAT_EQ(z0, v0.getZ());
	EXPECT_FLOAT_EQ(w0, v0.getW());

	// Vector4(const Vector3&, f32)
	{
		const Vector3 v3(x1, y1, z1);
		const Vector4 v4(v3, w1);
		EXPECT_FLOAT_EQ(x1, v4.getX());
		EXPECT_FLOAT_EQ(y1, v4.getY());
		EXPECT_FLOAT_EQ(z1, v4.getZ());
		EXPECT_FLOAT_EQ(w1, v4.getW());
	}

	// Vector4(const Vector4&)
	const Vector4 v1 = v0;
	EXPECT_FLOAT_EQ(v0.getX(), v1.getX());
	EXPECT_FLOAT_EQ(v0.getY(), v1.getY());
	EXPECT_FLOAT_EQ(v0.getZ(), v1.getZ());
	EXPECT_FLOAT_EQ(v0.getW(), v1.getW());

	// operator =
	Vector4 v2;
	v2 = v0;
	EXPECT_FLOAT_EQ(v0.getX(), v2.getX());
	EXPECT_FLOAT_EQ(v0.getY(), v2.getY());
	EXPECT_FLOAT_EQ(v0.getZ(), v2.getZ());
	EXPECT_FLOAT_EQ(v0.getW(), v2.getW());
}


TEST_F(Vector4Test, add)
{
	const Vector4 v0(x0, y0, z0, w0);
	const Vector4 v1(x1, y1, z1, w1);
	Vector4 v;

	// operator +=
	v = v0;
	v += v1;
	EXPECT_FLOAT_EQ(x0+x1, v.getX());
	EXPECT_FLOAT_EQ(y0+y1, v.getY());
	EXPECT_FLOAT_EQ(z0+z1, v.getZ());
	EXPECT_FLOAT_EQ(w0+w1, v.getW());

	// operator +
	v = v0 + v1;
	EXPECT_FLOAT_EQ(x0+x1, v.getX());
	EXPECT_FLOAT_EQ(y0+y1, v.getY());
	EXPECT_FLOAT_EQ(z0+z1, v.getZ());
	EXPECT_FLOAT_EQ(w0+w1, v.getW());
}


TEST_F(Vector4Test, sub)
{
	const Vector4 v0(x0, y0, z0, w0);
	const Vector4 v1(x1, y1, z1, w1);
	Vector4 v;

	// operator -=
	v = v0;
	v -= v1;
	EXPECT_FLOAT_EQ(x0-x1, v.getX());
	EXPECT_FLOAT_EQ(y0-y1, v.getY());
	EXPECT_FLOAT_EQ(z0-z1, v.getZ());
	EXPECT_FLOAT_EQ(w0-w1, v.getW());

	// operator -
	v = v0 - v1;
	EXPECT_FLOAT_EQ(x0-x1, v.getX());
	EXPECT_FLOAT_EQ(y0-y1, v.getY());
	EXPECT_FLOAT_EQ(z0-z1, v.getZ());
	EXPECT_FLOAT_EQ(w0-w1, v.getW());
}


TEST_F(Vector4Test, mul)
{
	const Vector4 v0(x0, y0, z0, w0);
	const Vector4 v1(x1, y1, z1, w1);
	const f32 f = randf();
	Vector4 v;

	// operator *=(const Vector4&)
	v = v0;
	v *= v1;
	EXPECT_FLOAT_EQ(x0*x1, v.getX());
	EXPECT_FLOAT_EQ(y0*y1, v.getY());
	EXPECT_FLOAT_EQ(z0*z1, v.getZ());
	EXPECT_FLOAT_EQ(w0*w1, v.getW());

	// operator *=(f32)
	v = v0;
	v *= f;
	EXPECT_FLOAT_EQ(x0*f, v.getX());
	EXPECT_FLOAT_EQ(y0*f, v.getY());
	EXPECT_FLOAT_EQ(z0*f, v.getZ());
	EXPECT_FLOAT_EQ(w0*f, v.getW());

	// operator *(const Vector4&, const Vector4&)
	v = v0 * v1;
	EXPECT_FLOAT_EQ(x0*x1, v.getX());
	EXPECT_FLOAT_EQ(y0*y1, v.getY());
	EXPECT_FLOAT_EQ(z0*z1, v.getZ());
	EXPECT_FLOAT_EQ(w0*w1, v.getW());

	// operator *(const Vector4&, f32)
	v = v0 * f;
	EXPECT_FLOAT_EQ(x0*f, v.getX());
	EXPECT_FLOAT_EQ(y0*f, v.getY());
	EXPECT_FLOAT_EQ(z0*f, v.getZ());
	EXPECT_FLOAT_EQ(w0*f, v.getW());

	// operator *(f32, const Vector4&)
	v = f * v1;
	EXPECT_FLOAT_EQ(f*x1, v.getX());
	EXPECT_FLOAT_EQ(f*y1, v.getY());
	EXPECT_FLOAT_EQ(f*z1, v.getZ());
	EXPECT_FLOAT_EQ(f*w1, v.getW());
}


TEST_F(Vector4Test, div)
{
	const Vector4 v0(x0, y0, z0, w0);
	const Vector4 v1(x1, y1, z1, w1);
	const f32 f = randf();
	Vector4 v;

	// operator /=(const Vector4&)
	v = v0;
	v /= v1;
	EXPECT_FLOAT_EQ(x0/x1, v.getX());
	EXPECT_FLOAT_EQ(y0/y1, v.getY());
	EXPECT_FLOAT_EQ(z0/z1, v.getZ());
	EXPECT_FLOAT_EQ(w0/w1, v.getW());

	// operator /=(f32)
	v = v0;
	v /= f;
	EXPECT_FLOAT_EQ(x0/f, v.getX());
	EXPECT_FLOAT_EQ(y0/f, v.getY());
	EXPECT_FLOAT_EQ(z0/f, v.getZ());
	EXPECT_FLOAT_EQ(w0/f, v.getW());

	// operator /(const Vector4&, const Vector4&)
	v = v0 / v1;
	EXPECT_FLOAT_EQ(x0/x1, v.getX());
	EXPECT_FLOAT_EQ(y0/y1, v.getY());
	EXPECT_FLOAT_EQ(z0/z1, v.getZ());
	EXPECT_FLOAT_EQ(w0/w1, v.getW());

	// operator /(const Vector4&, f32)
	v = v0 / f;
	EXPECT_FLOAT_EQ(x0/f, v.getX());
	EXPECT_FLOAT_EQ(y0/f, v.getY());
	EXPECT_FLOAT_EQ(z0/f, v.getZ());
	EXPECT_FLOAT_EQ(w0/f, v.getW());
}


TEST_F(Vector4Test, memberFunctions)
{
	const Vector4 v0(x0, y0, z0, w0);
	const Vector4 v1(x1, y1, z1, w1);
	const f32 f = randf();
	Vector4 v;

	// set & get
	v.set(x0, y0, z0, w0);
	EXPECT_FLOAT_EQ(x0, v.getX());
	EXPECT_FLOAT_EQ(y0, v.getY());
	EXPECT_FLOAT_EQ(z0, v.getZ());
	EXPECT_FLOAT_EQ(w0, v.getW());
}


